
`include "common_header.verilog"

//  *************************************************************************
//  File : gear_control_f
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized reproduction or use is expressly prohibited. 
//  Copyright (c) 2008 MorethanIP
//  Muenchner Strasse 199, 85757 Karlsfeld, Germany
//  info@morethanip.com
//  http://www.morethanip.com
//  *************************************************************************
//  Designed by : Serge S., Thomas Schrobenhauser
//  info@morethanip.com
//  *************************************************************************
//  Description: 10G Base-R PCS Receive Core : 
//               Block Sync inverse Gearbox control
//  Version    : $Id: gear_control_f.v,v 1.1 2011/07/14 20:27:38 dk Exp $
//  *************************************************************************

module gear_control_f (

   reset,
   clk,
   ck_ena,
   gctl_stop,
   slip,
   sync_tst,
   block_lock,
   sh_ok,
   sh_val,
   mux_data_cd,
   data_valid,
   data_valid_scr);

input   reset;                  //  asynch reset
input   clk;                    //  system clock
input   ck_ena;                 //  clock enable
input   gctl_stop;              //  stop slip and reset slip control to begin
input   slip;                   //  Slip - next candidate
input   [1:0] sync_tst;         //  Sync header to be tested
input   block_lock;             //  Lock state reached
output   sh_ok;                 //  Sync header good or not
output   sh_val;                //  Sync header valid
output   [6:0] mux_data_cd;     //  Data Mux
output   data_valid;            //  Data and Sync header valid for decoder and following
output   data_valid_scr;        //  Data valid for descrambler

wire    sh_ok; 
reg     sh_val; 
wire    [6:0] mux_data_cd; 
reg     data_valid; 
reg     data_valid_scr; 
reg     slip_s; 
reg     [6:0] cnt_mux_data; //  data-MUX control

// =====================================================================
//  Mux management  
// =====================================================================

always @(posedge clk or posedge reset)
   begin : p_state
   if (reset == 1'b 1)
      begin
      cnt_mux_data <= {7{1'b 0}};	
      slip_s <= 1'b 0;	
      sh_val <= 1'b 0;	
      data_valid <= 1'b 0;	
      data_valid_scr <= 1'b 0;	
      end
   else
      begin
      if (ck_ena == 1'b 1)
         begin
        // --------------------------------------
        //  66 cycles counter for data and sh muxes
        // --------------------------------------
         if( gctl_stop == 1'b 1 )
            begin
               cnt_mux_data <= 7'b 0000000;	
            end                
         else if (slip == 1'b 1)
            begin
            if (cnt_mux_data == 7'b 1000001)
               begin
               cnt_mux_data <= 7'b 0000000;	
               end
            else
               begin
               cnt_mux_data <= cnt_mux_data + 7'b 0000001;	
               end
            end

        // --------------------------------------------
        //  Sync header for testing valid
        // --------------------------------------------

         slip_s <= slip;	
        //  keep valid low as the next 2 words after slip are corrupted
         if ( (gctl_stop == 1'b 0 & (slip == 1'b 1 | slip_s == 1'b 1)) |
              (gctl_stop == 1'b 1 & slip == 1'b 1 ) )
            begin
            sh_val <= 1'b 0;	
            end
         else
            begin
            sh_val <= 1'b 1;	
            end

         end    //  ck_ena

      data_valid        <= block_lock & ck_ena;	
      data_valid_scr    <= ck_ena;	//  scrambler runs independent from block lock

      end
   end

// -------------------------
//  Command of Sync Header and Data Mux
// -------------------------
assign mux_data_cd = cnt_mux_data; 

// ---------------------------
//  Sync header good or not 
// ---------------------------
assign sh_ok = sync_tst[1] ^ sync_tst[0]; 

endmodule // module gear_control_f

